if {[lcontain [::jlib::capabilities transport] tls]} {
    set use_tls 1
} else {
    set use_tls 0
}

if {[lcontain [::jlib::capabilities transport] compress]} {
    set have_compress 1
} else {
    set have_compress 0
}

if {[lcontain [::jlib::capabilities auth] sasl]} {
    set have_sasl 1
} else {
    set have_sasl 0
}

if {[llength [::jlib::capabilities proxy]] > 1} {
    set have_proxy 1
} else {
    set have_proxy 0
}

if {[lcontain [::jlib::capabilities transport] http_poll]} {
    set have_http_poll 1
} else {
    set have_http_poll 0
}

custom::defgroup Warnings [::msgcat::mc "Warning display options."] \
    -group Tkabbur

if {$use_tls} {
    custom::defvar ::tls_warnings 1 [::msgcat::mc "Display SSL warnings."] \
	-group Warnings -type boolean
}


custom::defvar reasonlist {} [::msgcat::mc "List of logout reasons."] \
	-group Hidden

######################################################################

# connect errors mapping

array set connect_error [list \
	err_unknown 			[::msgcat::mc "Unknown error"] \
	timeout				[::msgcat::mc "Timeout"] \
	network-failure			[::msgcat::mc "Network failure"] \
	err_authorization_required	[::msgcat::mc "Proxy authentication required"] \
	err_version			[::msgcat::mc "Incorrect SOCKS version"] \
	err_unsupported_method		[::msgcat::mc "Unsupported SOCKS method"] \
	err_authentication_unsupported	[::msgcat::mc "Unsupported SOCKS authentication method"] \
	err_authorization		[::msgcat::mc "SOCKS authentication failed"] \
	rsp_failure			[::msgcat::mc "SOCKS request failed"] \
	rsp_errconnect			[::msgcat::mc "SOCKS server cannot identify username"] \
	rsp_erruserid			[::msgcat::mc "SOCKS server username identification failed"] \
	rsp_notallowed			[::msgcat::mc "SOCKS connection not allowed by ruleset"] \
	rsp_netunreachable		[::msgcat::mc "Network unreachable"] \
	rsp_hostunreachable		[::msgcat::mc "Host unreachable"] \
	rsp_refused			[::msgcat::mc "Connection refused by destination host"] \
	rsp_expired			[::msgcat::mc "TTL expired"] \
	rsp_cmdunsupported		[::msgcat::mc "SOCKS command not supported"] \
	rsp_addrunsupported		[::msgcat::mc "Address type not supported by SOCKS proxy"] \
	err_unknown_address_type	[::msgcat::mc "Unknown address type"]]

######################################################################
proc login {logindata} {
    global connect_error
    global login_after_time
    global login_after_id

    array set lc $logindata
    set user $lc(user)@$lc(server)/$lc(resource)
    if {[info exists login_after_id($user)]} {
	after cancel $login_after_id($user)
	unset login_after_id($user)
    }
    debugmsg login "Starting login"
    if {[catch {login_connect $logindata} connid] > 0} {
	# Nasty thing has happened.
	debugmsg login "Failed to connect: $connid"
	if {$lc(connect_forever)} {
	    login_retry $logindata
	} else {
	    if {[winfo exists .connect_err]} {
		destroy .connect_err
	    }
	    if {[info exists connect_error($connid)]} {
		set msg $connect_error($connid)
	    } else {
		set msg $connid
	    }
	    set res [MessageDlg .connect_err -width 600 -icon error \
		-message [format [::msgcat::mc "Failed to connect: %s"] $msg] \
		-type user -buttons [list abort [::msgcat::mc "Keep trying"]] \
		-default 0 -cancel 0]
	    if {$res} {
		set lc(connect_forever) 1
		set logindata [array get lc]
		login_retry $logindata
	    }
	}
	return
    }
    # OK, connected.
    debugmsg login "Connect successful ($user) $connid"
    set login_after_time 15000
    login_login $logindata $connid
}

proc login_retry {logindata} {
    global login_after_time
    global login_after_id

    if {![info exists login_after_time]} {set login_after_time 15000}
    if {$login_after_time < 1800000} {
	# 1800000 == 30 * 60 * 1000 == 30min
	# the sequence goes: 30s, 1min, 2min, 4min, 8min, 16min, 32min, 32min...
	set login_after_time [expr {$login_after_time * 2}]
    }
    array set lc $logindata
    set user $lc(user)@$lc(server)/$lc(resource)
    debugmsg login "Scheduling connect retry for $user in ${login_after_time}ms"
    if {[info exists login_after_id($user)]} {
	after cancel $login_after_id($user)
    }
    set login_after_id($user) [after $login_after_time [list login $logindata]]
}

proc client:tls_callback {connid args} {
    global tls_result tls_warnings
    global ssl_certificate_fields
    global tls_warning_info

    switch -- [lindex $args 0] {
	info {
	    set_status [lindex $args 4]
	}

	verify {
	    if {[cequal [set reason [lindex $args 5]] ""]} {
		return 1
	    }
	    set info [::msgcat::mc [string totitle $reason 0 0]]
	    append tls_warning_info($connid) "$info\n"
	    if {!$tls_warnings} {
		return 1
	    }
	    append info [::msgcat::mc ". Proceed?\n\n"]
	    foreach {k v} [lindex $args 3] {
		if {![cequal $v ""] && [info exists ssl_certificate_fields($k)]} {
		    append info [format "%s: %s\n" $ssl_certificate_fields($k) $v]
		}
	    }

	    set blocking [fconfigure [set fd [lindex $args 1]] -blocking]
	    fconfigure $fd -blocking 1
	    set readable [fileevent $fd readable]
	    fileevent $fd readable {}

	    set res [MessageDlg .tls_callback -aspect 50000 -icon warning \
			        -type user -buttons {yes no} -default 1 \
			        -cancel 1 \
			        -message [string trim $info]]

	    fileevent $fd readable $readable
	    fconfigure $fd -blocking $blocking

	    if {$res} {
		set res 0
	    } else {
		set res 1
	    }
	    return $res
	}

	error {
	    set tls_result [join [lrange $args 2 end] " "]
	}

	default {
	}
    }
}

proc login_connect {logindata} {
    global use_tls have_compress have_sasl have_http_poll have_proxy
    global tls_warning_info

    array set lc $logindata

    set connid [jlib::new -user $lc(user) \
			  -server $lc(server) \
			  -resource $lc(resource)]

    set tls_warning_info($connid) ""

    set args [list -password $lc(password) \
		   -allowauthplain $lc(allowauthplain) \
		   -allowgoogletoken $lc(allowgoogletoken)]
    if {$have_sasl} {
	lappend args -usesasl $lc(usesasl)
    }

    if {$have_proxy && ($lc(proxy) != "none")} {
	lappend args -proxy $lc(proxy)
	lappend args -proxyhost $lc(proxyhost)
	lappend args -proxyport $lc(proxyport)
	lappend args -proxyusername $lc(proxyusername)
	lappend args -proxypassword $lc(proxypassword)
	lappend args -proxyuseragent $lc(proxyuseragent)
    }

    set ascii_server [idna::domain_toascii $lc(server)]

    if {$have_http_poll && $lc(usehttppoll)} {
	if {$lc(pollurl) != ""} {
	    set url $lc(pollurl)
	} else {
	    set url [jlibdns::get_http_poll_url $ascii_server]
	}
	return [eval [list jlib::connect $connid \
				-transport http_poll \
				-polltimeout $lc(polltimeout) \
				-pollint $lc(pollmin) \
				-pollmin $lc(pollmin) \
				-pollmax $lc(pollmax) \
				-httpurl $url \
				-httpusekeys $lc(usepollkeys) \
				-httpnumkeys $lc(numberofpollkeys)] $args]
    } else {
	if {$have_compress && $lc(stream_options) == "compressed"} {
	    lappend args -usecompression 1
	}
   
	if {$lc(usealtserver)} {
	    set hosts {}
	} else {
	    set hosts [jlibdns::get_addr_port $ascii_server]
	    if {[lempty $hosts]} {
		set hosts [list [list $ascii_server 5222]]
	    }
	}
	set transport tcp
	set sslopts {}
	if {$use_tls} {
	    switch -- $lc(stream_options) {
		ssl {
		    set usestarttls 0
		    set transport tls
		    # Do some heuristic.
		    # Traditionally legacy SSL port is 5223,
		    # so let's add 1 to all ports from SRV reply
		    set hosts1 {}
		    foreach hp $hosts {
			lappend hosts1 \
				[list [lindex $hp 0] \
				      [expr {[lindex $hp 1] + 1}]]
		    }
		    set hosts $hosts1
		}
		encrypted {
		    set usestarttls 1
		}
		default {
		    set usestarttls 0
		}
	    }
	    set sslopts [list -usestarttls $usestarttls \
	                      -certfile $lc(sslcertfile) \
			      -cacertstore $lc(sslcacertstore) \
			      -keyfile $lc(sslkeyfile)]
	}

	if {$lc(usealtserver)} {
	    set hosts [list [list [idna::domain_toascii $lc(altserver)] $lc(altport)]]
	}

	return [eval [list jlib::connect $connid \
				-transport $transport \
				-hosts $hosts] \
				$sslopts $args]
    }
}

########################################################################

proc login_login {logindata connid} {
    global loginconf_hist
    global gr_nick gr_server gra_server

    array set lc $logindata
    set loginconf_hist($connid) $logindata

    set gr_nick $lc(user)
    set gr_server conference.$lc(server)
    set gra_server conference.$lc(server)

    jlib::login $connid [list recv_auth_result $connid $logindata]
}

########################################################################

set reconnect_retries 0

proc logout {{connid {}}} {
    global reconnect_retries
    global login_after_id

    # TODO
    foreach user [array names login_after_id] {
	after cancel $login_after_id($user)
	unset login_after_id($user)
    }

    hook::run predisconnected_hook $connid

    jlib::disconnect $connid
    if {$connid == {}} {
	roster::clean
    } else {
	roster::clean_connection $connid
    }

    disconnected $connid

    set reconnect_retries 0
}

proc client:disconnect {connid} {
    logout $connid
}

# TODO
proc client:reconnect {connid} {
    global reconnect_retries
    global loginconf_hist

    debugmsg login "RECONNECT $connid"

    hook::run predisconnected_hook $connid

    jlib::disconnect $connid
    roster::clean_connection $connid

    if {[jlib::connections] == {}} {
	set_status "Disconnected"
    }

    disconnected $connid

    if {[incr reconnect_retries] <= 3} {
        after 1000 [list login $loginconf_hist($connid)]
    }
}

proc connected {connid logindata} {
    hook::run connected_hook $connid
}

# TODO
proc disconnected {connid} {
    global curuserstatus userstatusdesc

    if {[jlib::connections] == {}} {
	set curuserstatus unavailable
	set userstatusdesc [::msgcat::mc "Not logged in"]
	hook::run change_our_presence_post_hook unavailable
    }
    hook::run disconnected_hook $connid
}

proc recv_auth_result {connid logindata res args} {
    array set lc $logindata

    if {$res == "OK"} {
	connected $connid $logindata
    } else {
	if {[winfo exists .auth_err$connid]} {
	    destroy .auth_err$connid
	}
	lassign [error_type_condition [lindex $args 0]] type cond
	if {($type == "sasl") || ($type == "auth" && $cond == "not-authorized")} {
#	    set res [MessageDlg .auth_err$connid -aspect 50000 -icon error \
#			 -message [format \
#			     [::msgcat::mc "Authentication failed: %s\nCreate new account?"] \
#			     [error_to_string [lindex $args 0]]] \
#			 -type user -buttons {yes no} -default 0 -cancel 1]
#	    if {!$res} {
#		login_register $lc(user) 
#		jlib::send_iq set \
#		    [jlib::wrapper:createtag query \
#			 -vars {xmlns jabber:iq:register} \
#			 -subtags [list [jlib::wrapper:createtag username \
#					     -chdata $lc(user)] \
#					[jlib::wrapper:createtag password \
#					     -chdata $lc(password)]]] \
#		    -connection $connid \
#		    -command [list recv_register_result $connid $logindata]
	    MessageDlg .auth_err$connid -aspect 50000 -icon error \
			 -message [format \
			     [::msgcat::mc "Authentication failed: %s"] \
			     [error_to_string [lindex $args 0]]] \
			 -type user -buttons ok -default 0
		return
	    }
	} else {
	    MessageDlg .auth_err$connid -aspect 50000 -icon error \
		-message [format \
			     [::msgcat::mc "Authentication failed: %s"] \
			     [error_to_string [lindex $args 0]]] \
		-type user -buttons {ok} -default 0 -cancel 0
	}
	logout $connid
    }
}

proc recv_register_result {connid logindata res args} {
    if {$res == "OK"} {
	jlib::disconnect
	login $logindata
    } else {
	if {[winfo exists .auth_err$connid]} {
	    destroy .auth_err$connid
	}
	MessageDlg .auth_err$connid -aspect 50000 -icon error \
	    -message [format [::msgcat::mc "Registration failed: %s"] \
			  [error_to_string [lindex $args 0]]] \
	    -type user -buttons ok -default 0 -cancel 0
	logout $connid
    }
}

# TODO
proc change_password_dialog {} {
    global oldpassword newpassword password

    set oldpassword ""
    set newpassword ""
    set password ""

    if {[winfo exists .passwordchange]} {
	destroy .passwordchange
    }
    
    Dialog .passwordchange -title [::msgcat::mc "Change password"] \
	-separator 1 -anchor e -default 0 -cancel 1

    .passwordchange add -text [::msgcat::mc "OK"] -command {
	destroy .passwordchange
	send_change_password
    }
    .passwordchange add -text [::msgcat::mc "Cancel"] -command [list destroy .passwordchange]


    set p [.passwordchange getframe]
    
    label $p.loldpass -text [::msgcat::mc "Old password:"]
    ecursor_entry [entry $p.oldpass -show * -textvariable oldpassword]
    label $p.lnewpass -text [::msgcat::mc "New password:"]
    ecursor_entry [entry $p.newpass -show * -textvariable newpassword]
    label $p.lpassword -text [::msgcat::mc "Repeat new password:"]
    ecursor_entry [entry $p.password -show * -textvariable password]

    grid $p.loldpass  -row 0 -column 0 -sticky e
    grid $p.oldpass   -row 0 -column 1 -sticky ew
    grid $p.lnewpass  -row 1 -column 0 -sticky e
    grid $p.newpass   -row 1 -column 1 -sticky ew
    grid $p.lpassword -row 2 -column 0 -sticky e
    grid $p.password  -row 2 -column 1 -sticky ew

    focus $p.oldpass
    .passwordchange draw

}

# TODO
proc send_change_password {} {
    global loginconf
    global oldpassword newpassword password

    if {$oldpassword != $loginconf(password)} {
	MessageDlg .auth_err -aspect 50000 -icon error \
	        -message [::msgcat::mc "Old password is incorrect"] \
		-type user -buttons ok -default 0 -cancel 0
	return
    }
    if {$newpassword != $password} {
	MessageDlg .auth_err -aspect 50000 -icon error \
	        -message [::msgcat::mc "New passwords do not match"] \
		-type user -buttons ok -default 0 -cancel 0
	return
    }

    set connid [jlib::route $loginconf(server)]

    jlib::send_iq set \
	    [jlib::wrapper:createtag query \
		    -vars {xmlns jabber:iq:register} \
		    -subtags [list [jlib::wrapper:createtag username \
					-chdata $loginconf(user)] \
				   [jlib::wrapper:createtag password \
					-chdata $password]]] \
	    -to $loginconf(server) \
	    -connection $connid \
	    -command recv_change_password_result
}

# TODO
proc recv_change_password_result {res args} {
    global loginconf
    global newpassword

    if {$res == "OK"} {
	MessageDlg .shpasswd_result -aspect 50000 -icon info \
		-message [::msgcat::mc "Password is changed"] \
		-type user -buttons ok -default 0 -cancel 0
	for {set i 1} {[info exists ::loginconf$i]} {incr i} {
	    if {!([info exists ::loginconf${i}(user)] && \
		    [info exists ::loginconf${i}(server)] && \
		    [info exists ::loginconf${i}(password)])} {
		continue
	    }
	    upvar ::loginconf${i}(user) user
	    upvar ::loginconf${i}(server) server
	    upvar ::loginconf${i}(password) password
	    if {[string equal $user $loginconf(user)] && \
		    [string equal $server $loginconf(server)] && \
		    [string equal $password $loginconf(password)]} {
		set password $newpassword
	    }
	}
	set loginconf(password) $newpassword
    } else {
	MessageDlg .shpasswd_result -aspect 50000 -icon error \
	    -message [format [::msgcat::mc "Password change failed: %s"] [error_to_string [lindex $args 0]]] \
	    -type user -buttons ok -default 0 -cancel 0
    }
}

# TODO


# REGISTER

proc aregister {logindata} {
    global connect_error
    global register_after_time
    global register_after_id

    array set lc $logindata
    set user $lc(user)@$lc(server)
    if {[info exists register_after_id($user)]} {
	after cancel $register_after_id($user)
	unset register_after_id($user)
    }
    debugmsg login "Starting register"
    if {[catch {register_connect $logindata} connid] > 0} {
	# Nasty thing has happened.
	debugmsg login "Failed to connect: $connid"
	    if {[winfo exists .connect_err]} {
		destroy .connect_err
	    }
	    if {[info exists connect_error($connid)]} {
		set msg $connect_error($connid)
	    } else {
		set msg $connid
	    }
	    set res [MessageDlg .connect_err -width 600 -icon error \
		-message [format [::msgcat::mc "Failed to connect: %s"] $msg] \
		-default 0 -cancel 0]
	return
    }
    # OK, connected.
    debugmsg login "Connect successful ($user) $connid"
    set register_after_time 15000
    register_register $logindata $connid
}

proc register_connect {logindata} {
    global use_tls have_compress have_proxy
    global tls_warning_info

    array set lc $logindata

    set connid [jlib::new -user $lc(user) \
			  -server $lc(server) \
			  -resource "your vater"]

    set tls_warning_info($connid) ""

    set args [list -password $lc(password) \
		   -allowauthplain 0 \
		   -allowgoogletoken 0]

    if {$have_proxy && ($lc(proxy) != "none")} {
	lappend args -proxy $lc(proxy)
	lappend args -proxyhost $lc(proxyhost)
	lappend args -proxyport $lc(proxyport)
	lappend args -proxyusername $lc(proxyusername)
	lappend args -proxypassword $lc(proxypassword)
	lappend args -proxyuseragent $lc(proxyuseragent)
    }

    set ascii_server [idna::domain_toascii $lc(server)]

	if {$have_compress && $lc(stream_options) == "compressed"} {
	    lappend args -usecompression 1
	}
   
	if {$lc(usealtserver)} {
	    set hosts {}
	} else {
	    set hosts [jlibdns::get_addr_port $ascii_server]
	    if {[lempty $hosts]} {
		set hosts [list [list $ascii_server 5222]]
	    }
	}
	set transport tcp
	set sslopts {}
	if {$use_tls} {
	    switch -- $lc(stream_options) {
		ssl {
		    set usestarttls 0
		    set transport tls
		    # Do some heuristic.
		    # Traditionally legacy SSL port is 5223,
		    # so let's add 1 to all ports from SRV reply
		    set hosts1 {}
		    foreach hp $hosts {
			lappend hosts1 \
				[list [lindex $hp 0] \
				      [expr {[lindex $hp 1] + 1}]]
		    }
		    set hosts $hosts1
		}
		encrypted {
		    set usestarttls 1
		}
		default {
		    set usestarttls 0
		}
	    }
	    set sslopts [list -usestarttls $usestarttls \
	                      -certfile $lc(sslcertfile) \
			      -cacertstore $lc(sslcacertstore) \
			      -keyfile $lc(sslkeyfile)]
	}

	if {$lc(usealtserver)} {
	    set hosts [list [list [idna::domain_toascii $lc(altserver)] $lc(altport)]]
	}

	return [eval [list jlib::connect $connid \
				-transport $transport \
				-hosts $hosts] \
				$sslopts $args]
    
}

########################################################################

proc register_register {logindata connid} {
    global regconf_hist
    global gr_nick gr_server gra_server

    array set lc $logindata
    set regconf_hist($connid) $logindata

    set gr_nick $lc(user)
    set gr_server conference.$lc(server)
    set gra_server conference.$lc(server)

    jlib::reguster $connid [list recv_register_register $connid $logindata]
}

proc recv_register_register {connid logindata res args} {

    array set lc $logindata
    if {$res == "OK"} {
#	connected $connid $logindata
	jlib::send_iq get \
	    [jlib::wrapper:createtag query \
		 -vars {xmlns jabber:iq:register} \
		 -subtags [list [jlib::wrapper:createtag username \
				     -chdata $lc(user)]]] \
	    -connection $connid \
	    -command [list recv_register_result $connid $logindata]
    } else {
	if {[winfo exists .reg_err$connid]} {
	    destroy .reg_err$connid
	}
#	lassign [error_type_condition [lindex $args 0]] type cond
	    MessageDlg .reg_err$connid -aspect 50000 -icon error \
			 -message [format \
			     [::msgcat::mc "Registration failed: %s"] \
			     [error_to_string [lindex $args 0]]] \
			 -type user -buttons ok -default 0
	logout $connid
    }
}

proc register_register2 {w connid logindata} {
	set f [$w.fields getframe]
	jlib::send_iq set \
		[jlib::wrapper:createtag query \
			-vars {xmlns jabber:iq:register} \
			-subtags [data::get_tags $f]] \
		-connection $connid \
		-command [list recv_register2_result $w $connid $logindata]
}

proc recv_register2_result {w connid logindata res child} {
	if {$res == "OK"} {
		MessageDlg .reg_err$connid -aspect 50000 -icon info \
		    -message [::msgcat::mc "Registration succeded"] \
		    -type user -buttons ok -default 0 -cancel 0
	} else {
		if {[winfo exists .reg_err$connid]} {
		    destroy .reg_err$connid
		}
		MessageDlg .reg_err$connid -aspect 50000 -icon error \
		    -message [format [::msgcat::mc "Registration failed: %s"] \
				  [error_to_string [lindex $child 0]]] \
		    -type user -buttons ok -default 0 -cancel 0
	}
	if {[info exists w]} {
		destroy $w
	}
	logout $connid
}

proc recv_register_result {connid logindata res child} {
	variable winid

    array set lc $logindata

    if {$res == "OK"} {
	jlib::wrapper:splitxml $child tag vars isempty chdata childrens
	set did 0
	foreach ch $childrens {
		jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 childrens1
		if {$tag1=="x" && [jlib::wrapper:getattr $vars1 xmlns]=="jabber:x:data"} {
			set did 1
			set xdata [find_xdata $childrens1]
			incr winid
			set w .register$winid
			if {[winfo exists $w]} {
				destroy $w
			}
			Dialog $w -modal none -separator 1 -anchor e -class XData \
				-default 0 -cancel 1
			set geometry [option get $w geometry XData]
			if {$geometry != ""} {
				wm geometry $w $geometry
			}
			set sw [ScrolledWindow $w.sw]
			set sf [ScrollableFrame $w.fields -constrainedwidth yes]
			set f [$sf getframe]
			$sw setwidget $sf
			set nf [frame $w.note]

			pack_note $nf $type $note
			set focus [data::fill_fields $f $xdata]

			$w add -text [::msgcat::mc "Submit"] \
				-command [list [namespace current]::register_register2 $w $connid $logindata]
			$w add -text [::msgcat::mc "Cancel"] \
				-command {
					logout $connid
				}

			$w configure -default 0

			bind $w <Escape> "$w invoke $cancel"
			bind $w <Destroy> [list data::cleanup $f]
			bindscroll $f $sf
			pack $nf -side top -expand no -fill x -padx 2m -pady 0m -in [$w getframe]
			pack $sw -side top -expand yes -fill both -padx 2m -pady 2m -in [$w getframe]
			update idletasks
			$nf configure -width [expr {[winfo reqwidth $f] + [winfo pixels $f 1c]}]
			if {$focus != ""} {
			        $w draw $focus
			} else {
			        $w draw
			}
			break
		}
		if {$tag1=="username" || $tag1=="password"} {
			set did 1
			jlib::send_iq set \
			    [jlib::wrapper:createtag query \
				 -vars {xmlns jabber:iq:register} \
				 -subtags [list [jlib::wrapper:createtag username \
						     -chdata $lc(user)] \
						[jlib::wrapper:createtag password \
						     -chdata $lc(password)]]] \
			    -connection $connid \
			    -command [list recv_register2_result {} $connid $logindata]
			break
		}
	}
	if {!$did} {
		MessageDlg .auth_err$connid -aspect 50000 -icon error \
		    -message [format [::msgcat::mc "No registration form received"] \
		  		[error_to_string [lindex $args 0]]] \
		    -type user -buttons ok -default 0 -cancel 0
		logout $connid
	}
    } else {
	if {[winfo exists .reg_err$connid]} {
	    destroy .reg_err$connid
	}
	MessageDlg .reg_err$connid -aspect 50000 -icon error \
	    -message [format [::msgcat::mc "Registration failed: %s"] \
			  [error_to_string [lindex $child 0]]] \
	    -type user -buttons ok -default 0 -cancel 0
	logout $connid
    }
}


